
import pygame
import random


def crop_image(image):
    """裁剪图片以去除白边"""
    width, height = image.get_size()
    left, right, top, bottom = width, 0, height, 0
    for x in range(width):
        for y in range(height):
            r, g, b, _ = image.get_at((x, y))
            # 假设白边是RGB值接近255的颜色，可根据实际情况调整
            if not (r > 240 and g > 240 and b > 240):
                if x < left:
                    left = x
                if x > right:
                    right = x
                if y < top:
                    top = y
                if y > bottom:
                    bottom = y
    if left < right and top < bottom:
        cropped = pygame.Surface((right - left + 1, bottom - top + 1))
        cropped.blit(image, (0, 0), (left, top, right - left + 1, bottom - top + 1))
        return cropped
    return image


# 粒子类
class Particle:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.radius = random.randint(2, 5)
        self.vx = random.uniform(-3, 3)
        self.vy = random.uniform(-5, -1)
        self.gravity = 0.1
        self.lifetime = random.randint(30, 60)
        self.initial_lifetime = self.lifetime

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += self.gravity
        self.lifetime -= 1

    def draw(self, surface):
        # 计算透明度，随生命周期减少
        alpha = int(255 * (self.lifetime / self.initial_lifetime))
        color_with_alpha = (*self.color, alpha)
        s = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA)
        pygame.draw.circle(s, color_with_alpha, (self.radius, self.radius), self.radius)
        surface.blit(s, (int(self.x - self.radius), int(self.y - self.radius)))

    def is_alive(self):
        return self.lifetime > 0


# 粒子系统类
class ParticleSystem:
    def __init__(self):
        self.particles = []

    def create_particles(self, x, y, count=30):
        colors = [(255, 255, 0), (255, 165, 0), (255, 69, 0), (255, 0, 0), (255, 192, 203)]
        for _ in range(count):
            color = random.choice(colors)
            self.particles.append(Particle(x, y, color))

    def update(self):
        self.particles = [p for p in self.particles if p.is_alive()]
        for particle in self.particles:
            particle.update()

    def draw(self, surface):
        for particle in self.particles:
            particle.draw(surface)


# 初始化Pygame
pygame.init()

# 游戏窗口设置
SCREEN_WIDTH = 750
SCREEN_HEIGHT = 650
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("羊了个羊")

# 调整卡片尺寸和间距
CARD_WIDTH = 80  # 增大卡片宽度
CARD_HEIGHT = 100  # 增大卡片高度
SPACING = 15  # 适当调整间距

# 游戏区域布局
GRID_ROWS = 3
GRID_COLS = 3
GRID_TOP = 100

# 加载牢大的图片
IMAGE_PATHS = [

    "tile1.png",
    "tile2.png",  # 假设这里有9.jpg, 10.jpg, 11.jpg，你需要替换为实际图片路径
    "tile3.png",
    "tile4.png",
    "tile5.png",
    "tile7.png",

]
IMAGES = []
for path in IMAGE_PATHS:
    image = pygame.image.load(path).convert()
    # 裁剪图片
    cropped_image = crop_image(image)
    # 按新的卡片尺寸缩放图片
    image = pygame.transform.smoothscale(cropped_image, (CARD_WIDTH, CARD_HEIGHT))
    IMAGES.append(image)

# 加载四张图片作为开始和结束页面的背景
BACKGROUND_IMAGES_PATHS = [
       "1.PNG",
    "2.PNG",
    "back2.png",
    "end.png",
    "mask.png",
    "t.png",
    "tile.png"

]
BACKGROUND_IMAGES = []
for path in BACKGROUND_IMAGES_PATHS:
    image = pygame.image.load(path).convert()
    # 使用smoothscale进行高清缩放
    image = pygame.transform.smoothscale(image, (SCREEN_WIDTH, SCREEN_HEIGHT))
    BACKGROUND_IMAGES.append(image)

# 开始页面背景图片索引和时间记录
start_page_background_index = 0
start_page_background_time = 0
# 游戏结束页面背景图片索引和时间记录
end_page_background_index = 0
end_page_background_time = 0

SLOT_COLOR = (200, 200, 200)
# 重新开始按钮设置
RESTART_BUTTON_WIDTH = 200
RESTART_BUTTON_HEIGHT = 50
restart_button_x = (SCREEN_WIDTH - RESTART_BUTTON_WIDTH) // 2
restart_button_y = SCREEN_HEIGHT // 2 + 50

# 道具相关设置
ITEM_WIDTH = 50
ITEM_HEIGHT = 50
ITEM_X = 20
ITEM_Y = SCREEN_HEIGHT - ITEM_HEIGHT - 20
item_count = 0

# 游戏状态枚举
START_PAGE = 0
GAME_PLAYING = 1
GAME_OVER = 2
game_state = START_PAGE

# 动画相关设置
ANIMATION_FRAMES = 20  # 动画帧数
animation_card = None
animation_start_pos = None
animation_end_pos = None
animation_frame = 0

# 创建粒子系统
particle_system = ParticleSystem()


# 初始化游戏
def init_game():
    global grid, slots, score, game_state, item_count, particle_system
    # 初始化卡片堆（每个位置3 - 4层）
    grid = []
    for row in range(GRID_ROWS):
        grid_row = []
        for col in range(GRID_COLS):
            layers = random.randint(3, 4)
            # 确保卡片类型数量为3的倍数
            stack = [random.randint(0, len(IMAGES) - 1) for _ in range(layers)]
            stack += [stack[-1]] * (3 - layers % 3) if layers % 3 != 0 else []
            grid_row.append(stack)
        grid.append(grid_row)
    slots = []
    score = 0
    game_state = GAME_PLAYING
    item_count = 1  # 初始附赠一个道具
    # 重置粒子系统
    particle_system = ParticleSystem()


# 开始按钮设置
BUTTON_WIDTH = 200
BUTTON_HEIGHT = 50
BUTTON_COLOR = (255, 255, 255)
button_x = (SCREEN_WIDTH - BUTTON_WIDTH) // 2
button_y = SCREEN_HEIGHT - BUTTON_HEIGHT - 50


def check_victory():
    """检查是否胜利"""
    for row in grid:
        for stack in row:
            if len(stack) > 0:
                return False
    return len(slots) == 0


# 主循环
clock = pygame.time.Clock()
running = True

while running:
    current_time = pygame.time.get_ticks()
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if game_state == START_PAGE:
                mouse_x, mouse_y = event.pos
                if (button_x <= mouse_x <= button_x + BUTTON_WIDTH and
                        button_y <= mouse_y <= button_y + BUTTON_HEIGHT):
                    init_game()
            elif game_state == GAME_OVER:
                mouse_x, mouse_y = event.pos
                if (restart_button_x <= mouse_x <= restart_button_x + RESTART_BUTTON_WIDTH and
                        restart_button_y <= mouse_y <= restart_button_y + RESTART_BUTTON_HEIGHT):
                    init_game()
            elif game_state == GAME_PLAYING:
                x, y = pygame.mouse.get_pos()
                # 检查是否点击了道具
                if ITEM_X <= x <= ITEM_X + ITEM_WIDTH and ITEM_Y <= y <= ITEM_Y + ITEM_HEIGHT:
                    if item_count > 0:
                        slots = []  # 消除槽中所有卡牌
                        item_count -= 1  # 减少道具数量
                else:
                    # 计算卡片堆的起始位置，使其居中
                    total_grid_width = GRID_COLS * (CARD_WIDTH + SPACING) - SPACING
                    start_x = (SCREEN_WIDTH - total_grid_width) // 2
                    # 计算点击位置
                    grid_col = (x - start_x) // (CARD_WIDTH + SPACING)
                    grid_row = (y - GRID_TOP) // (CARD_HEIGHT + SPACING)
                    # 检查点击范围
                    if 0 <= grid_row < GRID_ROWS and 0 <= grid_col < GRID_COLS:
                        if len(grid[grid_row][grid_col]) > 0:
                            # 取出顶层卡片
                            card = grid[grid_row][grid_col].pop()
                            # 计算起始位置
                            start_x_card = start_x + grid_col * (CARD_WIDTH + SPACING)
                            start_y_card = GRID_TOP + grid_row * (CARD_HEIGHT + SPACING) + len(
                                grid[grid_row][grid_col]) * 10
                            # 计算目标位置
                            slot_y = SCREEN_HEIGHT - CARD_HEIGHT - 20
                            total_slot_width = len(slots) * (CARD_WIDTH + 5) - 5
                            start_x_slot = (SCREEN_WIDTH - total_slot_width) // 2
                            end_x_card = start_x_slot + len(slots) * (CARD_WIDTH + 5)
                            end_y_card = slot_y

                            # 开始动画
                            animation_card = card
                            animation_start_pos = (start_x_card, start_y_card)
                            animation_end_pos = (end_x_card, end_y_card)
                            animation_frame = 0

    if game_state == START_PAGE:
        if current_time - start_page_background_time > 4000:  # 4秒间隔
            start_page_background_index = (start_page_background_index + 1) % len(BACKGROUND_IMAGES)
            start_page_background_time = current_time
        screen.blit(BACKGROUND_IMAGES[start_page_background_index], (0, 0))
        pygame.draw.rect(screen, BUTTON_COLOR, (button_x, button_y, BUTTON_WIDTH, BUTTON_HEIGHT))
        # 修改字体样式和大小，使用支持中文的字体
        font = pygame.font.SysFont('SimHei', 40)
        text = font.render("开始游戏", True, (0, 0, 0))
        text_rect = text.get_rect(center=(button_x + BUTTON_WIDTH // 2, button_y + BUTTON_HEIGHT // 2))
        screen.blit(text, text_rect)
    elif game_state == GAME_OVER:
        if current_time - end_page_background_time > 1000:  # 1秒间隔
            end_page_background_index = (end_page_background_index + 1) % len(BACKGROUND_IMAGES)
            end_page_background_time = current_time
        screen.blit(BACKGROUND_IMAGES[end_page_background_index], (0, 0))
        font = pygame.font.SysFont('SimHei', 60)
        text = font.render("游戏结束", True, (255, 0, 0))
        text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
        screen.blit(text, text_rect)
        restart_text = font.render("重新开始", True, (0, 0, 0))
        restart_text_rect = restart_text.get_rect(
            center=(restart_button_x + RESTART_BUTTON_WIDTH // 2, restart_button_y + RESTART_BUTTON_HEIGHT // 2))
        screen.blit(restart_text, restart_text_rect)
    elif game_state == GAME_PLAYING:
        # 绘制游戏界面
        screen.blit(BACKGROUND_IMAGES[0], (0, 0))  # 游戏进行时使用第一张背景图片

        # 更新粒子系统
        particle_system.update()

        # 计算卡片堆的起始位置，使其居中
        total_grid_width = GRID_COLS * (CARD_WIDTH + SPACING) - SPACING
        start_x = (SCREEN_WIDTH - total_grid_width) // 2

        # 绘制卡片堆（叠罗汉形式）
        for row in range(GRID_ROWS):
            for col in range(GRID_COLS):
                x = start_x + col * (CARD_WIDTH + SPACING)
                y = GRID_TOP + row * (CARD_HEIGHT + SPACING)
                stack = grid[row][col]
                for i, card_type in enumerate(stack):
                    offset = i * 10  # 每层卡片向下偏移10像素
                    image = IMAGES[card_type]
                    screen.blit(image, (x, y + offset))

        # 绘制槽位
        slot_y = SCREEN_HEIGHT - CARD_HEIGHT - 20
        total_slot_width = len(slots) * (CARD_WIDTH + 5) - 5
        start_x = (SCREEN_WIDTH - total_slot_width) // 2
        # 绘制白色长方形槽位背景
        pygame.draw.rect(screen, (255, 255, 255), (start_x, slot_y, total_slot_width, CARD_HEIGHT))
        for i, card in enumerate(slots):
            screen.blit(IMAGES[card], (start_x + i * (CARD_WIDTH + 5), slot_y))

        # 绘制动画中的卡片
        if animation_card is not None:
            if animation_frame < ANIMATION_FRAMES:
                # 计算当前位置
                current_x = animation_start_pos[0] + (animation_end_pos[0] - animation_start_pos[0]) * (
                        animation_frame / ANIMATION_FRAMES)
                current_y = animation_start_pos[1] + (animation_end_pos[1] - animation_start_pos[1]) * (
                        animation_frame / ANIMATION_FRAMES)
                screen.blit(IMAGES[animation_card], (current_x, current_y))
                animation_frame += 1
            else:
                # 动画结束，将卡片添加到槽中
                slots.append(animation_card)
                animation_card = None

                # 统计每种卡片的数量
                card_count = {}
                for c in slots:
                    if c in card_count:
                        card_count[c] += 1
                    else:
                        card_count[c] = 1

                # 检查是否有三个相同的卡片
                eliminated_card_type = None
                for card_type, count in card_count.items():
                    if count == 3:
                        # 移除三个相同的卡片
                        new_slots = []
                        removed_count = 0
                        for c in slots:
                            if c == card_type and removed_count < 3:
                                removed_count += 1
                            else:
                                new_slots.append(c)
                        slots = new_slots
                        score += 1
                        eliminated_card_type = card_type
                        break

                # 如果有消除，创建粒子效果
                if eliminated_card_type is not None:
                    # 计算消除位置（槽位中央）
                    center_x = start_x + total_slot_width // 2
                    center_y = slot_y + CARD_HEIGHT // 2
                    # 创建粒子
                    particle_system.create_particles(center_x, center_y, 50)

                # 检查失败条件
                if len(slots) > 7:
                    game_state = GAME_OVER
                # 检查胜利条件
                if check_victory():
                    game_state = GAME_OVER

        # 绘制粒子效果
        particle_system.draw(screen)

        # 绘制道具图标和数量
        pygame.draw.rect(screen, (255, 0, 0), (ITEM_X, ITEM_Y, ITEM_WIDTH, ITEM_HEIGHT))
        font = pygame.font.Font(None, 36)
        text = font.render(f"{item_count}", True, (255, 255, 255))
        text_rect = text.get_rect(center=(ITEM_X + ITEM_WIDTH // 2, ITEM_Y + ITEM_HEIGHT // 2))
        screen.blit(text, text_rect)

        # 绘制状态信息
        font = pygame.font.Font(None, 36)
        text = font.render(f"Score: {score}", True, (0, 0, 0))
        screen.blit(text, (20, 20))

    pygame.display.flip()
    clock.tick(30)

pygame.quit()